#pragma once

#include <iostream>
#include <vector>
#include <functional>
#include "Inet_Addr.hpp"
#include "ThreadPool.hpp"

using task_t = std::function<void()>;

class Route
{
private:
    std::vector<Inet_Addr> online_addr; // 维护一个在线列表
private:
    void check_online_user(Inet_Addr addr)
    {
        for (auto &c_addr : online_addr)
        {
            if (c_addr == addr)
            {
                printf("用户已存在\n");
                return;
            }
        }
        printf("[%s:%d] #不在在线列表中, 正在添加\n", addr.Ip().c_str(), addr.Port());
        online_addr.push_back(addr);
        printf("添加成功\n");
    }
    void forward_to_online_user(int sockfd, std::string recv_message, Inet_Addr who)
    {
        std::string message = "[" + who.Ip() + "] #";
        message += recv_message;
        for (auto &it : online_addr)
        {
            sockaddr_in local = it.Addr();
            int n = sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&local, sizeof(local));
            if (n < 0)
            {
                std::cout << "发送失败" << std::endl;
            }
            else
            {
                std::cout << "发送成功" << std::endl;
            }
        }
    }
    void offline(Inet_Addr addr)
    {
        auto it = online_addr.begin();
        while (it != online_addr.end())
        {
            if (*it == addr)
            {
                online_addr.erase(it);
                break;
            }
        }
    }

public:
    Route()
    {
    }
    void route(int sockfd, Inet_Addr addr, std::string recv_message)
    {
        if (recv_message == "Quit" || recv_message == "Q")
        {
            offline(addr);
        }

        // 判断该主机是否在在线列表中
        check_online_user(addr);
        // 主机在在线列表, 进行路由转发功能
        //forward_to_online_user(sockfd, recv_message, addr);
        task_t t = bind(&Route::forward_to_online_user, this, sockfd, recv_message, addr);
        ThreadPool<task_t>::getInstance()->Equeue(t);
    }
    ~Route()
    {
    }
};